#include "WiiCISPublicInclude.h"
#include "WiiCISWiimote.h"
#include "WiiCISPrivateInclude.h"

#include "WiiCISWiimoteState.h"

using namespace WiiCIS::IO;

namespace WiiCIS {

	Wiimote::Wiimote()
		: device(new Device()) {
	}

	Wiimote::~Wiimote() {
		delete device;
	}

	bool Wiimote::isConnected() const {
		return device->isConnected();
	}

	bool Wiimote::Connect() {
		device->Connect();

		return isConnected();
	}

	void Wiimote::Disconnect() {
		device->Disconnect();
	}

	bool Wiimote::getRumble() const {
		if (isConnected())
			return device->getRumble();
		else
			return false;
	}

	LedIndex Wiimote::getLeds() const {
		if (isConnected())
			return (LedIndex)device->getLeds();
		else
			return WMLED_NONE;
	}

	void Wiimote::setRumble(bool value) {
		if (isConnected())
			device->setRumble(value);
	}

	void Wiimote::setLeds(LedIndex value) {
		if (isConnected())
			device->setLeds(value);
	}

	const WiimoteState Wiimote::getState() {
		if (!isConnected())
			return WiimoteState();

		byte *buffer = device->Read();
		byte firstByte = *buffer;

		byte battery = 0;

		if (firstByte == INPUT_STATUS || firstByte == INPUT_READ || firstByte == INPUT_RESULT) {
			byte *packet = new byte[MAX_PAYLOAD];
			memcpy(packet, buffer, MAX_PAYLOAD);
		} else {
			byte *data = buffer;
			byte evt = *data;
			data++;

			switch (evt) {
			case REPORT_BTNS:
				break;
				// ...
			case REPORT_BTNS_ACC:
				break;
			case REPORT_BTNS_ACC_IR:
				break;
			case REPORT_BTNS_EXP:
				break;
			case REPORT_BTNS_ACC_EXP:
				break;
			case REPORT_BTNS_IR_EXP:
				break;
			case REPORT_BTNS_ACC_IR_EXP:
				break;
			case INPUT_STATUS:
				battery = data[5];
				break;
			}

			return WiimoteState(0, *reinterpret_cast<short *>(data));
		}
	}
}